package com.linser.gistools.utils;

import com.linser.gistools.utils.enums.CoordinateType;
import org.geotools.referencing.CRS;
import org.geotools.referencing.operation.DefaultCoordinateOperationFactory;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.CoordinateFilter;
import org.locationtech.jts.geom.Envelope;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CRSFactory;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.CoordinateOperation;
import org.opengis.referencing.operation.MathTransform;

/**
 * @author: linser
 * @Desc:
 * @create: 2024-02-05 14:37
 **/
public class TransformUtil {
    String[] cgcs2000 = new String[]{"4491", "4492", "4493", "4494", "4495", "4496", "4497", "4498", "4499", "4500", "4501", "4502", "4503", "4504", "4505", "4506", "4507", "4508", "4509", "4510", "4511", "4512", "4513", "4514", "4515", "4516", "4517", "4518", "4519", "4520", "4521", "4522", "4523", "4524", "4525", "4526", "4527", "4528", "4529", "4530", "4531", "4532", "4533", "4534", "4535", "4536", "4537", "4538", "4539", "4540", "4541", "4542", "4543", "4544", "4545", "4546", "4547", "4548", "4549", "4550", "4551", "4552", "4553", "4554"};
    private static CoordinateFilter coordinateFilter;
    public TransformUtil() {

    }
    public static Geometry transFormGeom(Geometry startGeo, CoordinateReferenceSystem sourceCRS, CoordinateReferenceSystem targetCRS) {
        Geometry geom = null;

        try {
            CoordinateFilter filter = getCoordinateFilter(sourceCRS, targetCRS);
            geom = startGeo.copy();
            geom.apply(filter);
            geom.setSRID(targetCRS.getCoordinateSystem().hashCode());
            geom.geometryChanged();
        } catch (Exception var5) {
            var5.printStackTrace();
        }

        return geom;
    }

    public static Geometry transFormGeom(Geometry startGeo, CoordinateReferenceSystem sourceCRS, CoordinateReferenceSystem targetCRS, CoordinateType coordinateType) {
        Geometry geom = null;

        try {
            CoordinateFilter filter = getCoordinateFilter(sourceCRS, targetCRS,coordinateType);
            geom = startGeo.copy();
            geom.apply(filter);
            geom.setSRID(targetCRS.getCoordinateSystem().hashCode());
            geom.geometryChanged();
        } catch (Exception var5) {
            var5.printStackTrace();
        }

        return geom;
    }
    public static Geometry transFormGeom(Geometry startGeo, CoordinateType coordinateType) {
        Geometry geom = null;

        try {
            CoordinateFilter filter = getCoordinateFilter(coordinateType);
            geom = startGeo.copy();
            geom.apply(filter);
            geom.geometryChanged();
        } catch (Exception var5) {
            var5.printStackTrace();
        }

        return geom;
    }

    public static CoordinateFilter getCoordinateFilter(CoordinateReferenceSystem sourceCRS, CoordinateReferenceSystem targetCRS) throws FactoryException {
        //设置宽松模式 忽略4490坐标系中的七参数的要求
        MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
        return new CoordinateFilter() {
            public void filter(Coordinate coordinate) {
                try {
                    double[] targetXyz = new double[]{coordinate.x, coordinate.y, coordinate.z};
                    transform.transform(new double[]{coordinate.x, coordinate.y, coordinate.z},0,targetXyz,0,1);
                    // 将 Coordinate 转换为 double 数组
                    if (CRS.getAxisOrder(targetCRS).equals(CRS.AxisOrder.EAST_NORTH)) {
                        coordinate.setOrdinate(0, targetXyz[0]);
                        coordinate.setOrdinate(1, targetXyz[1]);
                    } else {
                        coordinate.setOrdinate(0, targetXyz[1]);
                        coordinate.setOrdinate(1, targetXyz[0]);
                    }
                    if (targetXyz.length > 2 && !Double.isNaN(targetXyz[2])) {
                        coordinate.setOrdinate(2, targetXyz[2]);
                    }
                } catch (Exception var3) {
                    var3.printStackTrace();
                }

            }
        };
    }
    public static CoordinateFilter getCoordinateFilter(CoordinateReferenceSystem sourceCRS, CoordinateReferenceSystem targetCRS , CoordinateType coordinateType) throws FactoryException {
        //设置宽松模式 忽略4490坐标系中的七参数的要求
        MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
        return new CoordinateFilter() {
            public void filter(Coordinate coordinate) {
                try {
                    double[] targetXyz = new double[]{coordinate.x, coordinate.y, coordinate.z};
                    transform.transform(new double[]{coordinate.x, coordinate.y, coordinate.z},0,targetXyz,0,1);
                    // 将 Coordinate 转换为 double 数组
                    if (coordinateType == CoordinateType.LonLat) {
                        coordinate.setOrdinate(0, targetXyz[0]);
                        coordinate.setOrdinate(1, targetXyz[1]);
                    } else {
                        coordinate.setOrdinate(0, targetXyz[1]);
                        coordinate.setOrdinate(1, targetXyz[0]);
                    }
                    if (targetXyz.length > 2 && !Double.isNaN(targetXyz[2])) {
                        coordinate.setOrdinate(2, targetXyz[2]);
                    }
                } catch (Exception var3) {
                    var3.printStackTrace();
                }

            }
        };
    }

    public static CoordinateFilter getCoordinateFilter(CoordinateType coordinateType) throws FactoryException {
        return new CoordinateFilter() {
            public void filter(Coordinate coordinate) {
                try {
                    double[] targetXyz = new double[]{coordinate.x, coordinate.y, coordinate.z};
                    // 将 Coordinate 转换为 double 数组
                    if (coordinateType == CoordinateType.LonLat) {
                        coordinate.setOrdinate(0, targetXyz[0]);
                        coordinate.setOrdinate(1, targetXyz[1]);
                    } else {
                        coordinate.setOrdinate(0, targetXyz[1]);
                        coordinate.setOrdinate(1, targetXyz[0]);
                    }
                    if (targetXyz.length > 2 && !Double.isNaN(targetXyz[2])) {
                        coordinate.setOrdinate(2, targetXyz[2]);
                    }
                } catch (Exception var3) {
                    var3.printStackTrace();
                }

            }
        };
    }

    public static CoordinateFilter getCoordinateFilter(MathTransform transform) {
        return new CoordinateFilter() {
            public void filter(Coordinate coordinate) {
                try {
                    Coordinate transformedCoordinate = new Coordinate();
                    double[] targetXyz = new double[]{coordinate.x, coordinate.y, coordinate.z};
                    transform.transform(new double[]{coordinate.x, coordinate.y, coordinate.z},0,targetXyz,0,1);
                    // 将 Coordinate 转换为 double 数组
                    coordinate.setOrdinate(0, targetXyz[0]);
                    coordinate.setOrdinate(1, targetXyz[1]);
                    if (targetXyz.length > 2 && !Double.isNaN(targetXyz[2])) {
                        coordinate.setOrdinate(2, targetXyz[2]);
                    }
                } catch (Exception var3) {
                    var3.printStackTrace();
                }

            }
        };
    }
}
